package com.jzo2o.common.model;

import cn.hutool.core.util.ArrayUtil;
import cn.hutool.http.HttpStatus;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;

import java.nio.charset.StandardCharsets;

/**
 * 接口响应结果模型类，统一封装接口返回的状态码、消息和数据
 * @param <T> 响应数据的类型
 */
@Data
public class Result<T> {

    public static final int SUCCESS = 200; // 响应成功
    public static final String OK = "OK"; // 响应消息
    public static final int FAILED = 1; // 响应失败

    /** 成功响应的字节数组（{"code":200,"msg":"OK","data": {}}） */
    public static final byte[] OK_BYTES =
            String.format("{\"code\":%d,\"msg\":\"%s\",\"data\": {}}", SUCCESS, OK).getBytes(StandardCharsets.UTF_8);
    /** 成功响应前缀字节数组（{"code":200,"msg":"OK","data": ） */
    public static final byte[] OK_PREFIX =
            String.format("{\"code\":%d,\"msg\":\"%s\",\"data\": ", SUCCESS, OK).getBytes(StandardCharsets.UTF_8);
    /** 成功响应后缀字节数组（}） */
    public static final byte[] OK_SUFFIX = "}".getBytes(StandardCharsets.UTF_8);
    /** 成功响应字符串类型前缀字节数组（{"code":200,"msg":"OK","data":） */
    public static final byte[] OK_STR_PREFIX =
            String.format("{\"code\":%d,\"msg\":\"%s\",\"data\":", SUCCESS, OK).getBytes(StandardCharsets.UTF_8);
    /** 成功响应字符串类型后缀字节数组（}） */
    public static final byte[] OK_STR_SUFFIX = "}".getBytes(StandardCharsets.UTF_8);
    /** 请求成功消息（"OK"） */
    public static final String REQUEST_OK = "OK";

    /** 业务状态码，200-成功，其它-失败 */
    @ApiModelProperty(value = "业务状态码，200-成功，其它-失败")
    private int code;
    /** 响应消息 */
    @ApiModelProperty(value = "响应消息", example = "OK")
    private String msg;
    /** 响应数据 */
    @ApiModelProperty(value = "响应数据")
    private T data;
    /** 请求id */
    @ApiModelProperty(value = "请求id", example = "1af123c11412e")
    private String requestId;

    /**
     * 构建无数据的成功响应
     * @return 无数据的Result<Void>成功实例
     */
    public static Result<Void> ok() {
        return new Result<Void>(HttpStatus.HTTP_OK, REQUEST_OK, null);
    }

    /**
     * 构建带数据的成功响应
     * @param data 响应数据
     * @param <T> 响应数据类型
     * @return 带数据的Result<T>成功实例
     */
    public static <T> Result<T> ok(T data) {
        return new Result<>(HttpStatus.HTTP_OK, REQUEST_OK, data);
    }

    /**
     * 构建默认错误码（400）的失败响应
     * @param msg 错误消息
     * @param <T> 响应数据类型（无实际数据，为泛型兼容）
     * @return Result<T>失败实例
     */
    public static <T> Result<T> error(String msg) {
        return new Result<>(HttpStatus.HTTP_BAD_REQUEST, msg, null);
    }

    /**
     * 构建指定错误码的失败响应
     * @param code 错误状态码
     * @param msg 错误消息
     * @param <T> 响应数据类型（无实际数据，为泛型兼容）
     * @return Result<T>失败实例
     */
    public static <T> Result<T> error(int code, String msg) {
        return new Result<>(code, msg, null);
    }

    /** 无参构造器 */
    public Result() {
    }

    /**
     * 全参构造器
     * @param code 状态码
     * @param msg 响应消息
     * @param data 响应数据
     */
    public Result(int code, String msg, T data) {
        this.code = code;
        this.msg = msg;
        this.data = data;
    }

    /**
     * 判断响应是否成功（状态码是否为200）
     * @return true-成功，false-失败
     */
    public boolean success() {
        return code == HttpStatus.HTTP_OK;
    }

    /**
     * 获取无数据的成功响应字节数组
     * @return 成功响应字节数组
     */
    public static byte[] plainOk() {
        return OK_BYTES;
    }

    /**
     * 构建带数据的成功响应字节数组（根据数据格式自动适配前缀）
     * @param data 响应数据字节数组
     * @return 完整的成功响应字节数组
     */
    public static byte[] plainOk(byte[] data) {
        if(data == null || data.length <= 0){
            return OK_BYTES;
        }
        byte b = data[0];
        // 若数据以"["或"{"开头（JSON数组/对象），使用OK_PREFIX和OK_SUFFIX
        if (b == 91 || b == 123) {
            return ArrayUtil.addAll(OK_PREFIX, data, OK_SUFFIX);
        }
        // 其他格式数据，使用OK_STR_PREFIX和OK_STR_SUFFIX
        return ArrayUtil.addAll(OK_STR_PREFIX, data, OK_STR_SUFFIX);
    }
}
